"""
Utilities related to office

"""

import os
from pathlib import Path
from typing import Any, Callable, Dict, List, Optional, Tuple, Union, Iterable

import win32com.client as cc
from docxcompose.composer import Composer
from docx import Document


@export
def open_word_app(visible=False):
    wd = cc.gencache.EnsureDispatch("Word.Application")
    wd.Visible = visible
    return wd


@export
class WordAppScope:
    def __init__(self):
        self.wd: Optional[Any] = None
        self.doc: Optional[Any] = None

    def __enter__(self):
        self.wd = open_word_app()
        return self

    def __exit__(self, *arg):
        assert self.wd
        self.close_file()
        self.wd.Quit()
        self.wd = None

    def open_file(self, path: Union[str, Path]) -> "WordAppScope":
        assert self.wd
        path = Path(path)
        self.file_path = path
        # self.close_file()
        self.doc = self.wd.Documents.Open(os.path.abspath(path), False)
        return self

    def export_pdf(self, path: str):
        assert self.doc
        self.doc.ExportAsFixedFormat(os.path.abspath(path), 17)
        print(f"-> export pdf: {path}, done")

    def close_file(self, save=False):
        wdDoNotSaveChanges = 0
        wdSaveChanges = -1
        if self.doc is not None:
            if save:
                self.doc.Close(wdSaveChanges)
            else:
                self.doc.Close(wdDoNotSaveChanges)
            self.doc = None

    def save_as_docx(self, dest_dir: Optional[Path]) -> Path:
        # doc = word.Documents.Open(file, False)#打开文档，不提示转换确认框
        new_name = change_file_name_extension(self.file_path.name, ".docx")
        if dest_dir is None:
            dest_dir = self.file_path.parent
        new_file = dest_dir / new_name
        self.doc.SaveAs(new_file.absolute(), 12)
        self.doc.Close()
        return new_file


def combine_docx(
    master: Path,
    sub: Path,
    dest: Path,
    *,
    convert_sub_to_docx=False,
    convert_dest_dir: Optional[Path] = None,
):
    if not os.path.exists(sub):  # 待合并文件必须存在
        return False

    if master.suffix != ".docx":  # 主文件必须是docx格式（可以不存在）
        raise ValueError("只支持docx 文件")

    sub_docx = sub
    if sub.suffix != ".docx":
        if convert_sub_to_docx and convert_dest_dir is not None:
            sub_docx = WordAppScope().open_file(sub).save_as_docx(convert_dest_dir)
        else:
            raise ValueError("只支持docx 文件")

    if os.path.exists(master):
        doc_master = Document(master)
        doc_master.add_page_break()
        cp = Composer(doc_master)
        cp.append(Document(sub_docx))
    else:
        # master不存在，则sub直接给master
        doc_master = Document(sub_docx)

    doc_master.save(dest)
    return True
